package top.chaol.t55557reader;

import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.content.Context;
import android.hardware.usb.UsbManager;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.util.Log;
import android.widget.Toast;

import java.lang.ref.WeakReference;


import me.drakeet.support.toast.ToastCompat;

import static top.chaol.t55557reader.Constants.OK;
import static top.chaol.t55557reader.UsbSerial.ErrorCode.SUCCESS;

public class MainActivity extends Activity {

	public static final String TAG = "cn.wch.wchusbdriver";

//	public readThread handlerThread;
//	protected final Object ThreadLock = new Object();
	private IntentFilter usbDeviceStateFilter;
	private BroadcastReceiver mUsbReceiver;
	private ProgressDialog waitingDialog;
	private TextView readText;
	private TextView writeText;
	private TextView statusCode, statusStr;
//	private Spinner baudSpinner;
//	private Spinner stopSpinner;
//	private Spinner dataSpinner;
//	private Spinner paritySpinner;
//	private Spinner flowSpinner;
	private boolean isOpen;
	private Handler handler;
	private MainActivity activity;

	private Button writeButton, openButton, readButton;

//	public int actualNumBytes;
//
//	public int numBytes;
//	public byte count;
//	public int status;
//	public byte writeIndex = 0;
//	public byte readIndex = 0;

//	public int baudRate;
//	public byte baudRate_byte;
//	public byte stopBit;
//	public byte dataBit;
//	public byte parity;
//	public byte flowControl;

	private T55557Card card;
	private UsbSerial serial;
	private byte[] cmdData;

	public MainActivity() {
	}

//	public boolean isConfiged = false;
//	public boolean READ_ENABLE = false;
//	public SharedPreferences sharePrefSettings;
//	public String act_string;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		initUI();

		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);// 保持常亮的屏幕的状态
		isOpen = false;
//		configButton.setEnabled(false);
		writeButton.setEnabled(false);
		readButton.setEnabled(false);
		activity = this;
		card = new T55557Card();
		serial = new UsbSerial(this);
		
		//打开流程主要步骤为ResumeUsbList，UartInit
		openButton.setOnClickListener(arg0 -> {
			if (!isOpen) {
				waitingDialog.show();
				serial.openSerial(new UsbSerial.CallBack() {
					@Override
					public void run(UsbSerial.ErrorCode res) {
						String tips = getTips(res);
						if (res == SUCCESS) {
							serial.configSerial();
							writeButton.setEnabled(true);
							readButton.setEnabled(true);
							openButton.setText(R.string.close);
							isOpen = true;
						} else {
							isOpen = false;
						}
						ToastCompat.makeText(activity, tips, Toast.LENGTH_SHORT).show();
						waitingDialog.dismiss();
					}

					@Override
					public void run(UsbSerial.ErrorCode status, byte[] res) {
						waitingDialog.dismiss();
					}
				});
			} else {
				if(serial != null) {
					serial.closeSerial();
				}
				isOpen = false;
				readButton.setEnabled(isOpen);
				writeButton.setEnabled(isOpen);
				openButton.setText(R.string.open);
			}
		});

//		configButton.setOnClickListener(arg0 -> {
//
//			if (MyApp.driver.SetConfig(9600, (byte)8, (byte)1, (byte)0, (byte)0)) {
//				Toast.makeText(MainActivity.this, "串口设置成功!",
//						Toast.LENGTH_SHORT).show();
//			} else {
//				Toast.makeText(MainActivity.this, "串口设置失败!",
//						Toast.LENGTH_SHORT).show();
//			}
//		});
		writeButton.setOnClickListener(arg0 -> {
			if(!isOpen) {
				ToastCompat.makeText(activity, activity.getString(R.string.open_device_please), Toast.LENGTH_SHORT).show();
				return;
			}
			waitingDialog.show();
			serial.makeCard(new UsbSerial.CallBack() {
				@Override
				public void run(UsbSerial.ErrorCode res) {
//					if(res == SUCCESS) {
////						Snackbar.make(writeButton, getTips(SUCCESS), Snackbar.LENGTH_SHORT).show();
//						writeText.setText(getTips(SUCCESS));
//					}
					writeText.setText(getTips(res));
					waitingDialog.dismiss();
				}

				@Override
				public void run(UsbSerial.ErrorCode status, byte[] res) {
					waitingDialog.dismiss();
				}
			});
		});
		readButton.setOnClickListener(v -> {
//			clearButton.callOnClick();
			waitingDialog.show();
			serial.readCard(new UsbSerial.CallBack() {
				@Override
				public void run(UsbSerial.ErrorCode res) {
					readText.setText(getTips(res));
					waitingDialog.dismiss();
				}

				@Override
				public void run(UsbSerial.ErrorCode status, byte[] res) {
					waitingDialog.dismiss();
					if (status != SUCCESS) {
//						Snackbar.make(readButton, getTips(status), Snackbar.LENGTH_SHORT).show();
						readText.setText(getTips(status));
						return;
					} else {
						readText.setText(toHexString(res, res.length));
					}
				}
			});
		});

		((Button) findViewById(R.id.button)).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				serial.closeSerial();
				System.exit(0);
			}
		});

		handler = new MyHandler(this);
		mUsbReceiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				String action = intent.getAction();
				if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
					serial.closeSerial();
					openButton.setText(activity.getText(R.string.open));
//					configButton.setEnabled(false);
					writeButton.setEnabled(false);
					readButton.setEnabled(false);
					isOpen = false;
				}
			}
		};
		usbDeviceStateFilter = new IntentFilter();
		usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);

	}

	//处理界面
	private void initUI() {
		readText = findViewById(R.id.ReadValues);
		writeText = findViewById(R.id.WriteValues);
//		configButton = findViewById(R.id.configButton);
		writeButton = findViewById(R.id.WriteButton);
		readButton = findViewById(R.id.ReadButton);
		openButton = findViewById(R.id.open_device);
//		clearButton = findViewById(R.id.clearButton);

		waitingDialog = new ProgressDialog(MainActivity.this);
		waitingDialog.setTitle(getString(R.string.loading));
		waitingDialog.setMessage(getString(R.string.waiting_operation));
		waitingDialog.setIndeterminate(true);
		waitingDialog.setCancelable(false);

//		clearButton.setOnClickListener(arg0 -> readText.setText(""));
	}

	/**
	 * 将byte[]数组转化为String类型
	 * @param arg
	 *            需要转换的byte[]数组
	 * @param length
	 *            需要转换的数组长度
	 * @return 转换后的String队形
	 */
	private String toHexString(byte[] arg, int length) {
		String result = "";
		if (arg != null) {
			for (int i = 0; i < length; i++) {
				result = result
						+ (Integer.toHexString(
								arg[i] < 0 ? arg[i] + 256 : arg[i]).length() == 1 ? "0"
								+ Integer.toHexString(arg[i] < 0 ? arg[i] + 256
										: arg[i])
								: Integer.toHexString(arg[i] < 0 ? arg[i] + 256
										: arg[i])) + " ";
			}
			return result;
		}
		return "";
	}

	/**
	 * 将String转化为byte[]数组
	 * @param arg
	 *            需要转换的String对象
	 * @return 转换后的byte[]数组
	 */
	private byte[] toByteArray(String arg) {
		if (arg != null) {
			/* 1.先去除String中的' '，然后将String转换为char数组 */
			char[] NewArray = new char[1000];
			char[] array = arg.toCharArray();
			int length = 0;
			for (char c : array) {
				if (c != ' ') {
					NewArray[length] = c;
					length++;
				}
			}
			/* 将char数组中的值转成一个实际的十进制数组 */
			int EvenLength = (length % 2 == 0) ? length : length + 1;
			if (EvenLength != 0) {
				int[] data = new int[EvenLength];
				data[EvenLength - 1] = 0;
				for (int i = 0; i < length; i++) {
					if (NewArray[i] >= '0' && NewArray[i] <= '9') {
						data[i] = NewArray[i] - '0';
					} else if (NewArray[i] >= 'a' && NewArray[i] <= 'f') {
						data[i] = NewArray[i] - 'a' + 10;
					} else if (NewArray[i] >= 'A' && NewArray[i] <= 'F') {
						data[i] = NewArray[i] - 'A' + 10;
					}
				}
				/* 将 每个char的值每两个组成一个16进制数据 */
				byte[] byteArray = new byte[EvenLength / 2];
				for (int i = 0; i < EvenLength / 2; i++) {
					byteArray[i] = (byte) (data[i * 2] * 16 + data[i * 2 + 1]);
				}
				return byteArray;
			}
		}
		return new byte[] {};
	}
	
	/**
	 * 将String转化为byte[]数组
	 * @param arg
	 *            需要转换的String对象
	 * @return 转换后的byte[]数组
	 */
	private byte[] toByteArray2(String arg) {
		if (arg != null) {
			/* 1.先去除String中的' '，然后将String转换为char数组 */
			char[] NewArray = new char[1000];
			char[] array = arg.toCharArray();
			int length = 0;
			for (int i = 0; i < array.length; i++)
				if (array[i] != ' ') {
					NewArray[length] = array[i];
					length++;
				}
			NewArray[length] = 0x0D;
			NewArray[length + 1] = 0x0A;
			length += 2;

			byte[] byteArray = new byte[length];
			for (int i = 0; i < length; i++) {
				byteArray[i] = (byte)NewArray[i];
			}
			return byteArray;
	
		}
		return new byte[] {};
	}

	@Override
	public void onResume(){
		registerReceiver(mUsbReceiver, usbDeviceStateFilter);
		super.onResume();
	}

	@Override
	public void onPause(){
		if (waitingDialog.isShowing())
			waitingDialog.dismiss();
		unregisterReceiver(mUsbReceiver);
		Log.d(TAG, "UnregisterReceiver");
		super.onPause();
	}

	private String getTips(UsbSerial.ErrorCode code) {
		String tips = "";
		switch (code) {
			case ERROR_WRITE_FAILED:
				tips = activity.getString(R.string.error_write_failed);
				break;
			case ERROR_CONNECT_FAILED:
				tips = activity.getString(R.string.error_connect_failed);
				break;
			case ERROR_NO_VALID_DEVICE:
				tips = activity.getString(R.string.error_no_valid_device);
				break;
			case ERROR_NULL_LIST:
				tips = activity.getString(R.string.error_null_list);
				break;
			case ERROR_PERMISSION_DENIED:
				tips = activity.getString(R.string.error_permission_denied);
				break;
			case ERROR_NULL_MANAGER:
				tips = activity.getString(R.string.error_null_manager);
				break;
			case ERROR_READ_FAILED:
				tips = activity.getString(R.string.error_read_failed);
				break;
			case SUCCESS:
				tips = activity.getString(R.string.success_open_serial);
				break;
            case ERROR_CARD_NOT_EXIST:
                tips = getString(R.string.error_card_not_exist);
                break;
            case ERROR_CARD_TYPE:
                tips = getString(R.string.error_card_type);
                break;
            case ERROR_CMD_CODE:
                tips = getString(R.string.error_cmd_error);
                break;
            case ERROR_KNOW:
                tips = getString(R.string.error_unknow);
                break;
            case ERROR_PARAM:
                tips = getString(R.string.error_param);
                break;
            case ERROR_NULL_DEVICE:
                tips = getString(R.string.error_null_device);
                break;
            case ERROR:
                tips = activity.getString(R.string.error);
                break;
		}
		return tips;
	}

	static class MyHandler extends Handler {
		private WeakReference<MainActivity> mActivity;

		MyHandler(MainActivity activity) {
			mActivity = new WeakReference<MainActivity>(activity);
		}

		@Override
		public void handleMessage(Message msg) {
			MainActivity activity = mActivity.get();
			if (activity != null) {
				switch (msg.what) {
					case OK:
						activity.statusCode.setText(Integer.toHexString(activity.card.getResponseStruct().getStatus()));
						activity.statusStr.setText(activity.getTips(activity.card.getResponseStatusMessage()));
						activity.readText.append(activity.card.getResponseStruct().toHexString());
						break;
				}
			}
		}
	}
}
